/**
 *******************************************************************************
 * @file  gpio/gpio_output/source/main.c
 * @brief Main program of GPIO for the Device Driver Library.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2020-09-15       CDT             First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by HDSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "hc32_ddl.h"
#include "modem.h"

/**
 * @addtogroup HC32M423_DDL_Examples
 * @{
 */

/**
 * @addtogroup GPIO_OUTPUT
 * @{
 */

/*******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/*******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/
/* KEY1 */
#define BSP_KEY1_INT_CH                 (EXTINT_CH05)

/*******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/

/*******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/*******************************************************************************
 * Local variable definitions ('static')
 ******************************************************************************/
static uint8_t u8ExtIntFlag = 1U, u8LedState = 0U;
static uint16_t u16TickValue = 0U;

/*******************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/
/**
 * @brief  SysTick interrupt callback function.
 * @param  None
 * @retval None
 */
void SysTick_IrqHandler(void)
{
    SysTick_IncTick();
    if (0U != u8ExtIntFlag)
    {
        if (++u16TickValue >= 100U)
        {
            u16TickValue = 0U;
            switch (++u8LedState)
            {
                case 1U: BSP_LED_Toggle(LED_RED); break;
                case 2U: BSP_LED_Toggle(LED_GREEN); break;
                case 3U: BSP_LED_Toggle(LED_BLUE); break;
                default: u8LedState = 0U; break;
            }
        }
    }
}

/**
 * @brief  KEY1(SW1) External interrupt.
 * @param  None
 * @retval None
 */
void ExtInt05_SWInt13_IrqHandler(void)
{
    u8ExtIntFlag = !u8ExtIntFlag;
    if (0U == u8ExtIntFlag)
    {
        u16TickValue = 0U;
        u8LedState = 0U;
        BSP_LED_Off(LED_RED | LED_GREEN | LED_BLUE);
    }
    EXTINT_ClearExtIntStatus(BSP_KEY1_INT_CH);
}

/**
 * @brief  Configure CRC.
 * @param  None
 * @retval None
 */
void CRC_Config(void)
{
    CLK_FcgPeriphClockCmd(CLK_FCG_CRC, Enable);
}

/**
 * @brief  Configure USART.
 * @param  None
 * @retval None
 */
void USART_Config(void)
{
    const stc_usart_uart_init_t stcUartInit = {
        .u32Baudrate         = USART_BAUDRATE,
        .u32FirstBit         = USART_FIRST_BIT_LSB,
        .u32StopBit          = USART_STOPBIT_1BIT,
        .u32Parity           = USART_PARITY_NONE,
        .u32DataWidth        = USART_DATA_WIDTH_8BIT,
        .u32ClockMode        = USART_INTERNCLK_NONE_OUTPUT,
        .u32ClockDiv         = USART_CLK_DIV1,
        .u32OverSampleBit    = USART_OVER_SAMPLE_8BIT,
        .u32StartBitPolarity = USART_START_BIT_FALLING,
    };

    /* Configure USART RX/TX pin. */
    GPIO_SetFunc(USART_RX_PORT, USART_RX_PIN, USART_RX_FUNC);
    GPIO_SetFunc(USART_TX_PORT, USART_TX_PIN, USART_TX_FUNC);

    /* Enable peripheral clock */
    CLK_FcgPeriphClockCmd(USART_UNIT_CLOCK, Enable);
    /* Initialize USART function. */
    USART_UART_Init(USART_UNIT, &stcUartInit);
    /* Enable RX/TX function */
    USART_FuncCmd(USART_UNIT, (USART_RX | USART_TX), Enable);
}

/**
 * @brief  MCU Peripheral registers write unprotected.
 * @param  None
 * @retval None
 * @note Comment/uncomment each API depending on APP requires.
 */
static void Peripheral_WE(void)
{
    /* Unlock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */
    GPIO_Unlock();
    /* Unlock PWC, CLK, LVD registers, @ref PWC_REG_Write_Unlock_Code for details */
    PWC_Unlock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1);
    /* Unlock all EFM registers */
    EFM_Unlock();
}

/**
 * @brief  MCU Peripheral registers write protected.
 * @param  None
 * @retval None
 * @note Comment/uncomment each API depending on APP requires.
 */
static void Peripheral_WP(void)
{
    /* Lock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */
    GPIO_Lock();
    /* Lock PWC, CLK, LVD registers, @ref PWC_REG_Write_Unlock_Code for details */
    // PWC_Lock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1 | PWC_UNLOCK_CODE_2);
    /* Lock all EFM registers */
    // EFM_Lock();
}

/**
 * @brief  Main function of GPIO project
 * @param  None
 * @retval int32_t return value, if needed
 */
int32_t main(void)
{
    /* Peripheral registers write unprotected */
    Peripheral_WE();
    /* Configure BSP */
    BSP_CLK_Init();
    BSP_LED_Init();
    BSP_KEY_Init(BSP_KEY_MD_EXTINT);
    /* SysTick configuration */
    SysTick_Init(1000U);
    /* Configure Peripheral */
    CRC_Config();
    USART_Config();
    /* Peripheral registers write protected */
    Peripheral_WP();

    while (1)
    {
        Modem_Process(1000);
    }
}

/**
 * @}
 */

/**
 * @}
 */

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
